#在GF(2^8)上的运算
#函数可以接受16进制

import exsystem

#多项式加法,接收二进制，返回二进制
def plus(a,b):
    a = int(a,2)
    b = int(b,2)
    c = a^b
    return Gbin(c)

#接受16进制，返回16进制
def hexplus(a,b):
    a = int(a,16)
    b = int(b,16)
    c = a^b
    return exsystem.detohex(c)


def pplus(a,b):
    a = int(a,2)
    b = int(b,2)
    c = a^b
    return '{:0>9b}'.format(c)

#多项式加法，接受整数，返回整数
def decplus(a,b):
    c = a^b
    return c

#将整数转为二进制
def Gbin(a):
    return '{:0>8b}'.format(a)

#将二进制字符串标准化
def normal(a):
    return '{:0>8}'.format(a)

def minus(a,b):
    return pplus(a,b)

def decminus(a,b):
    
    return decplus(a,b)

#x*f(x)
def xf(s):
    if s[0] == '0':
        a = normal(s[1:] + '0')
    else:
        a = plus(s[1:] + '0', '00011011')
    return a

def multi(a,b):
    a = normal(a)
    b = normal(b)
    if(b == '00000000'):
        return '00000000'
    le = len(b)
    result = ''
    tmp = a[:]
    for i in range(1,le+1):
        if b[le - i] == '1':
            if result == '':
                result = tmp[:]
            else:
                result = plus(result, tmp)
        tmp = xf(tmp)
    return result

#接受16进制,返回16进制
def hexmulti(a,b):
    a = exsystem.hextoBi(a)
    b = exsystem.hextoBi(b)
    c = exsystem.tohex(multi(a,b))
    return c


def decmulti(a,b):
    return multi(Gbin(a), Gbin(b))

#a/b
def divide(a,b):
    a = '{:0>9}'.format(a)
    b = '{:0>9}'.format(b)
    re = ''
    while True:
        div = b.index('1') - a.index('1')
        if div < 0:
            break
        else:
            tmp = '{:0<9}'.format(b[div:])
            a = pplus(a,tmp)
            if re == '':
                re = '000000000'
                re = '{:0<9}'.format(re[:8-div] + '1')
            else:
                s = '000000000'
                s = '{:0<9}'.format(s[:8 - div] + '1')
                re = pplus(re, s)
    a = a[1:]
    re = re[1:]
    return (a,re)

def decdivide(a,b):
    return divide(Gbin(a),Gbin(b))



#在GF(2^8)中求逆元,a为既约多项式
def inverse(a,b):
    a = '{:0>9}'.format(a)
    b = '{:0>9}'.format(b)
    w1 = '00000001'
    w2 =  '00000000'
    v1 = '00000000'
    v2 = '00000001'
    re = ''
    if b == '000000000':
        return b[1:]
    if b == '000000001':
        return b[1:]
    while True:
        s = b[:]
        b, re = divide(a,b)
        w3 = plus(w1,multi(w2,re))
        v3 = plus(v1,multi(v2,re))
        a = s
        w1 = w2
        w2 = w3
        v1 = v2
        v2 = v3
        if b == '00000001':
            break
    return v2

#方便AES计算
def decinverse(a,b):
    return inverse(a,Gbin(b))
    

#b为16进制,返回16进制
def hexinverse(a,b):
    b = int(b,16)
    return exsystem.tohex(decinverse(a,b))
    







            



    
